//
//  UIView+RCSToast.m
//  RCS
//
//  Created by apple on 14-10-11.
//  Copyright (c) 2014年 Chinasofti. All rights reserved.
//

#import "UIView+RCSToast.h"
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>

// general appearance
static const CGFloat RCSToastMaxWidth            = 0.8;      // 80% of parent view width
static const CGFloat RCSToastMaxHeight           = 0.8;      // 80% of parent view height
static const CGFloat RCSToastHorizontalPadding   = 10.0;
static const CGFloat RCSToastVerticalPadding     = 10.0;
static const CGFloat RCSToastCornerRadius        = 10.0;
static const CGFloat RCSToastOpacity             = 1.0;
static const CGFloat RCSToastFontSize            = 16.0;
static const CGFloat RCSToastMaxTitleLines       = 0;
static const CGFloat RCSToastMaxMessageLines     = 0;
static const CGFloat RCSToastFadeDuration        = 0.2;

// shadow appearance
static const CGFloat RCSToastShadowOpacity       = 0.8;
static const CGFloat RCSToastShadowRadius        = 6.0;
static const CGSize  RCSToastShadowOffset        = { 4.0, 4.0 };
static const BOOL    RCSToastDisplayShadow       = NO;

// display duration and position
static const CGFloat RCSToastDefaultDuration     = 0.5;
static const NSString * RCSToastDefaultPosition  = @"bottom";

// image view size
static const CGFloat RCSToastImageViewWidth      = 80.0;
static const CGFloat RCSToastImageViewHeight     = 80.0;

// activity
static const CGFloat RCSToastActivityWidth       = 100.0;
static const CGFloat RCSToastActivityHeight      = 100.0;
static const NSString * RCSToastActivityDefaultPosition = @"center";
static const NSString * RCSToastActivityViewKey  = @"RCSRCSToastActivityViewKey";
static const int tostid = 99999;


@interface UIView (RCSPrivate)

- (CGPoint)rcscenterPointForPosition:(id)position withToast:(UIView *)toast;
- (UIView *)rcsviewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image;

@end


@implementation UIView (RCSToast)

#pragma mark - Toast Methods

-(void)rcsHidenToastView{
    
//    for (UIWindow* window in [UIApplication sharedApplication].windows){
//        for (NSObject* ob in window.subviews){
//            if ([ob isKindOfClass:[UIView class]]){
//                UIView *tmpV = (UIView *)ob;
//                if (tmpV.tag == tostid) {
//                    if (tmpV) {
//                        [tmpV removeFromSuperview];
//                        tmpV.alpha = 0.0;
//                    }
//                }
//            }
//        }
//    }
//
    UIView* toastView = [self viewWithTag:tostid];
    if (toastView) {
        [toastView removeFromSuperview];
        toastView.alpha = 0.0;
    }
}

- (void)rcsmakeToast:(NSString *)message {
    [self rcsmakeToast:message duration:RCSToastDefaultDuration position:RCSToastDefaultPosition];
}

- (void)rcsmakeToast:(NSString *)message duration:(CGFloat)interval position:(id)position {
    [self rcsHidenToastView];
    UIView *toast = [self viewForMessage:message title:nil image:nil];
    [self rcsshowToast:toast duration:interval position:position];
}

- (void)rcsmakeToast:(NSString *)message duration:(CGFloat)interval position:(id)position title:(NSString *)title {
    UIView *toast = [self viewForMessage:message title:title image:nil];
    [self rcsshowToast:toast duration:interval position:position];
}

- (void)rcsmakeToast:(NSString *)message duration:(CGFloat)interval position:(id)position image:(UIImage *)image {
    UIView *toast = [self viewForMessage:message title:nil image:image];
    [self rcsshowToast:toast duration:interval position:position];
}

- (void)rcsmakeToast:(NSString *)message duration:(CGFloat)interval  position:(id)position title:(NSString *)title image:(UIImage *)image {
    UIView *toast = [self viewForMessage:message title:title image:image];
    [self rcsshowToast:toast duration:interval position:position];
}

- (void)rcsshowToast:(UIView *)toast {
    [self rcsshowToast:toast duration:RCSToastDefaultDuration position:RCSToastDefaultPosition];
}

- (void)rcsshowToast:(UIView *)toast duration:(CGFloat)interval position:(id)point {

    [self rcsHidenToastView];
    
    toast.center = [self rcscenterPointForPosition:point withToast:toast];
    toast.alpha = 0.0;
    [self addSubview:toast];
    
    [UIView animateWithDuration:RCSToastFadeDuration
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         toast.alpha = 1.0;
                     } completion:^(BOOL finished) {

                         [UIView animateWithDuration:RCSToastFadeDuration
                                               delay:interval
                                             options:UIViewAnimationOptionCurveEaseIn
                                          animations:^{
                                              toast.alpha = 0.0;
                                          } completion:^(BOOL finished) {
                                              toast.alpha = 0.0;
                                              [toast removeFromSuperview];
                                             
                                          }];
                     }];
}

- (void)rcsshowToastForChat:(NSString *)message bShowKeyBoard:(BOOL)isShowKeyBoard
{
    if (message == nil)
    {
        return;
    }
    
    [self rcsHidenToastView];
    
    //背景
    UIView *toastView = [[UIView alloc] init];
    toastView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
    toastView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.6];
    
    //内容
    UILabel *msgLabel = [[UILabel alloc] init];
    msgLabel.font = [UIFont systemFontOfSize:12.0];
    msgLabel.textColor = [UIColor whiteColor];
    msgLabel.backgroundColor = [UIColor clearColor];
    msgLabel.text = message;
    msgLabel.lineBreakMode = NSLineBreakByTruncatingTail;
    msgLabel.frame = CGRectMake(10, 10, self.bounds.size.width - 20, 20);
    
    if (isShowKeyBoard) {
        toastView.frame = CGRectMake(0, self.bounds.size.height - 40 - 45 - 216, self.bounds.size.width,40);
    }
    else{
        toastView.frame = CGRectMake(0, self.bounds.size.height - 40 - 45, self.bounds.size.width,40);
    }
    
    [toastView addSubview:msgLabel];
    toastView.alpha = 0.0;
    [self addSubview:toastView];
    
    [UIView animateWithDuration:RCSToastFadeDuration
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         toastView.alpha = RCSToastShadowOpacity;
                     } completion:^(BOOL finished) {
                         
                         [UIView animateWithDuration:RCSToastFadeDuration
                                               delay:RCSToastDefaultDuration
                                             options:UIViewAnimationOptionCurveEaseIn
                                          animations:^{
                                              toastView.alpha = 0.0;
                                          } completion:^(BOOL finished) {
                                              [toastView removeFromSuperview];
                                          }];
                         
                     }];
}

#pragma mark - Toast Activity Methods

- (void)rcsmakeToastActivity {
    [self rcsmakeToastActivity:RCSToastActivityDefaultPosition];
}

- (void)rcsmakeToastActivity:(id)position {

    [self rcsHidenToastView];

    // sanity
    UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &RCSToastActivityViewKey);
    if (existingActivityView != nil) return;
    
    UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, RCSToastActivityWidth, RCSToastActivityHeight)];
    activityView.center = [self rcscenterPointForPosition:position withToast:activityView];
    activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:RCSToastOpacity];
    activityView.alpha = 0.0;
    activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
    activityView.layer.cornerRadius = RCSToastCornerRadius;
    
    if (RCSToastDisplayShadow) {
        activityView.layer.shadowColor = [UIColor blackColor].CGColor;
        activityView.layer.shadowOpacity = RCSToastShadowOpacity;
        activityView.layer.shadowRadius = RCSToastShadowRadius;
        activityView.layer.shadowOffset = RCSToastShadowOffset;
    }
    
    UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2);
    [activityView addSubview:activityIndicatorView];
    [activityIndicatorView startAnimating];
    
    // associate ourselves with the activity view
    objc_setAssociatedObject (self, &RCSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self addSubview:activityView];
    
    [UIView animateWithDuration:RCSToastFadeDuration
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         activityView.alpha = 1.0;
                     } completion:nil];
}

- (void)rcshideToastActivity {
    
    [self rcsHidenToastView];
    
    UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &RCSToastActivityViewKey);
    if (existingActivityView != nil) {
        [UIView animateWithDuration:RCSToastFadeDuration
                              delay:0.0
                            options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState)
                         animations:^{
                             existingActivityView.alpha = 0.0;
                         } completion:^(BOOL finished) {
                             [existingActivityView removeFromSuperview];
                             objc_setAssociatedObject (self, &RCSToastActivityViewKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
                         }];
    }
}

- (void)rcsmakeToastActivityWithMessage:(NSString *)message
{
    [self rcsHidenToastView];
    
    UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &RCSToastActivityViewKey);
    if (existingActivityView != nil) return;
    
    UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, RCSToastActivityWidth*1.4, RCSToastActivityHeight*1.4)];
    activityView.center = [self rcscenterPointForPosition:RCSToastActivityDefaultPosition withToast:activityView];
    activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8];
    activityView.alpha = 0.0;
    activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
    activityView.layer.cornerRadius = RCSToastCornerRadius;
    
    if (RCSToastDisplayShadow) {
        activityView.layer.shadowColor = [UIColor blackColor].CGColor;
        activityView.layer.shadowOpacity = RCSToastShadowOpacity;
        activityView.layer.shadowRadius = RCSToastShadowRadius;
        activityView.layer.shadowOffset = RCSToastShadowOffset;
    }
    
    UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2 , activityView.bounds.size.height / 2 - 20);
    [activityView addSubview:activityIndicatorView];
    [activityIndicatorView startAnimating];
    
    UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(5, activityView.bounds.size.height - 50, activityView.bounds.size.width - 10, 30)];
    label.text = message;
    label.font = [UIFont boldSystemFontOfSize:16];
    label.textColor = [UIColor whiteColor];
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor clearColor];
    [activityView addSubview:label];
    
    // associate ourselves with the activity view
    objc_setAssociatedObject (self, &RCSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    [self addSubview:activityView];
    [UIView animateWithDuration:RCSToastFadeDuration
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         activityView.alpha = 1.0;
                     } completion:nil];
    
}

- (void)rcsmakeToastResultWithMessage:(NSString *)message isSuccess:(BOOL)success
{
    [self rcsHidenToastView];

    UIView *resultView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, RCSToastActivityWidth*1.4, RCSToastActivityHeight*1.4)];
    resultView.center = [self rcscenterPointForPosition:RCSToastActivityDefaultPosition withToast:resultView];
    resultView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8];
    resultView.alpha = 0.0;
    resultView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
    resultView.layer.cornerRadius = RCSToastCornerRadius;
    
    if (RCSToastDisplayShadow) {
        resultView.layer.shadowColor = [UIColor blackColor].CGColor;
        resultView.layer.shadowOpacity = RCSToastShadowOpacity;
        resultView.layer.shadowRadius = RCSToastShadowRadius;
        resultView.layer.shadowOffset = RCSToastShadowOffset;
    }
    
    if (success) {
        UIImageView *successImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"toast_success"]];
        successImageView.center = CGPointMake(resultView.bounds.size.width / 2 , resultView.bounds.size.height / 2 - 20);
        [resultView addSubview:successImageView];
    }else {
        UIImageView *failureImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"toast_failure"]];
        failureImageView.center = CGPointMake(resultView.bounds.size.width / 2 , resultView.bounds.size.height / 2 - 20);
        [resultView addSubview:failureImageView];
    }
    
    UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(5, resultView.bounds.size.height - 50, resultView.bounds.size.width - 10, 30)];
    label.text = message;
    label.font = [UIFont boldSystemFontOfSize:16];
    label.textColor = [UIColor whiteColor];
    label.textAlignment = NSTextAlignmentCenter;
    label.backgroundColor = [UIColor clearColor];
    [resultView addSubview:label];
    
    [self addSubview:resultView];
    [UIView animateWithDuration:RCSToastFadeDuration
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         resultView.alpha = 1.0;
                     } completion:^(BOOL finished) {
                         
                         [UIView animateWithDuration:RCSToastFadeDuration
                                               delay:RCSToastDefaultDuration
                                             options:UIViewAnimationOptionCurveEaseIn
                                          animations:^{
                                              resultView.alpha = 0.0;
                                          } completion:^(BOOL finished) {
                                              [resultView removeFromSuperview];
                                          }];
                     }];
    
}

#pragma mark - Private Methods

- (CGPoint)rcscenterPointForPosition:(id)point withToast:(UIView *)toast {
    if([point isKindOfClass:[NSString class]]) {
        // convert string literals @"top", @"bottom", @"center", or any point wrapped in an NSValue object into a CGPoint
        if([point caseInsensitiveCompare:@"top"] == NSOrderedSame) {
            return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + RCSToastVerticalPadding);
        } else if([point caseInsensitiveCompare:@"bottom"] == NSOrderedSame) {
            return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - 60);
        } else if([point caseInsensitiveCompare:@"center"] == NSOrderedSame) {
            return CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
        }
    } else if ([point isKindOfClass:[NSValue class]]) {
        return [point CGPointValue];
    }
    
    NSLog(@"Warning: Invalid position for toast.");
    return [self rcscenterPointForPosition:RCSToastDefaultPosition withToast:toast];
}

- (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image {
    // sanity
    if((message == nil) && (title == nil) && (image == nil)) return nil;
    
    // dynamically build a toast view with any combination of message, title, & image.
    UILabel *messageLabel = nil;
    UILabel *titleLabel = nil;
    UIImageView *imageView = nil;
    
    // create the parent view
    UIView *wrapperView = [[UIView alloc] init];
    wrapperView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
    wrapperView.layer.cornerRadius = RCSToastCornerRadius;
    
    if (RCSToastDisplayShadow) {
        wrapperView.layer.shadowColor = [UIColor blackColor].CGColor;
        wrapperView.layer.shadowOpacity = RCSToastShadowOpacity;
        wrapperView.layer.shadowRadius = RCSToastShadowRadius;
        wrapperView.layer.shadowOffset = RCSToastShadowOffset;
    }
    
    wrapperView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:RCSToastOpacity];
    
    if(image != nil) {
        imageView = [[UIImageView alloc] initWithImage:image];
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        imageView.frame = CGRectMake(RCSToastHorizontalPadding, RCSToastVerticalPadding, RCSToastImageViewWidth, RCSToastImageViewHeight);
    }
    
    CGFloat imageWidth, imageHeight, imageLeft;
    
    // the imageView frame values will be used to size & position the other views
    if(imageView != nil) {
        imageWidth = imageView.bounds.size.width;
        imageHeight = imageView.bounds.size.height;
        imageLeft = RCSToastHorizontalPadding;
    } else {
        imageWidth = imageHeight = imageLeft = 0.0;
    }
    
    if (title != nil) {
        titleLabel = [[UILabel alloc] init];
        titleLabel.numberOfLines = RCSToastMaxTitleLines;
        titleLabel.font = [UIFont boldSystemFontOfSize:RCSToastFontSize];
        titleLabel.textAlignment = NSTextAlignmentLeft;
        titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
        titleLabel.textColor = [UIColor whiteColor];
        titleLabel.backgroundColor = [UIColor clearColor];
        titleLabel.alpha = 1.0;
        titleLabel.text = title;
        
        // size the title label according to the length of the text
        CGSize maxSizeTitle = CGSizeMake((self.bounds.size.width * RCSToastMaxWidth) - imageWidth, self.bounds.size.height * RCSToastMaxHeight);
        CGSize expectedSizeTitle = [title sizeWithFont:titleLabel.font constrainedToSize:maxSizeTitle lineBreakMode:titleLabel.lineBreakMode];
        titleLabel.frame = CGRectMake(0.0, 0.0, expectedSizeTitle.width, expectedSizeTitle.height);
    }
    
    if (message != nil) {
        messageLabel = [[UILabel alloc] init];
        messageLabel.numberOfLines = RCSToastMaxMessageLines;
        messageLabel.font = [UIFont systemFontOfSize:RCSToastFontSize];
        messageLabel.lineBreakMode = NSLineBreakByWordWrapping;
        messageLabel.textColor = [UIColor whiteColor];
        messageLabel.backgroundColor = [UIColor clearColor];
        messageLabel.alpha = 1.0;
        messageLabel.text = message;
        
        // size the message label according to the length of the text
        CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * RCSToastMaxWidth) - imageWidth, self.bounds.size.height * RCSToastMaxHeight);
        CGSize expectedSizeMessage = [message sizeWithFont:messageLabel.font constrainedToSize:maxSizeMessage lineBreakMode:messageLabel.lineBreakMode];
        messageLabel.frame = CGRectMake(0.0, 0.0, expectedSizeMessage.width, expectedSizeMessage.height);
    }
    
    // titleLabel frame values
    CGFloat titleWidth, titleHeight, titleTop, titleLeft;
    
    if(titleLabel != nil) {
        titleWidth = titleLabel.bounds.size.width;
        titleHeight = titleLabel.bounds.size.height;
        titleTop = RCSToastVerticalPadding;
        titleLeft = imageLeft + imageWidth + RCSToastHorizontalPadding;
    } else {
        titleWidth = titleHeight = titleTop = titleLeft = 0.0;
    }
    
    // messageLabel frame values
    CGFloat messageWidth, messageHeight, messageLeft, messageTop;
    
    if(messageLabel != nil) {
        messageWidth = messageLabel.bounds.size.width;
        messageHeight = messageLabel.bounds.size.height;
        messageLeft = imageLeft + imageWidth + RCSToastHorizontalPadding;
        messageTop = titleTop + titleHeight + RCSToastVerticalPadding;
    } else {
        messageWidth = messageHeight = messageLeft = messageTop = 0.0;
    }
    
    
    CGFloat longerWidth = MAX(titleWidth, messageWidth);
    CGFloat longerLeft = MAX(titleLeft, messageLeft);
    
    // wrapper width uses the longerWidth or the image width, whatever is larger. same logic applies to the wrapper height
    CGFloat wrapperWidth = MAX((imageWidth + (RCSToastHorizontalPadding * 2)), (longerLeft + longerWidth + RCSToastHorizontalPadding));
    CGFloat wrapperHeight = MAX((messageTop + messageHeight + RCSToastVerticalPadding), (imageHeight + (RCSToastVerticalPadding * 2)));
    
    wrapperView.frame = CGRectMake(0.0, 0.0, wrapperWidth, wrapperHeight);
    
    if(titleLabel != nil) {
        titleLabel.frame = CGRectMake(titleLeft, titleTop, titleWidth, titleHeight);
        [wrapperView addSubview:titleLabel];
    }
    
    if(messageLabel != nil) {
        messageLabel.frame = CGRectMake(messageLeft, messageTop, messageWidth, messageHeight);
        [wrapperView addSubview:messageLabel];
    }
    
    if(imageView != nil) {
        [wrapperView addSubview:imageView];
    }
    
    wrapperView.tag = tostid;
    
    return wrapperView;
}

@end
